package com.ld.security.common.quartz.modules.job.service.impl;


import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ld.security.common.core.base.SuperPo;
import com.ld.security.common.core.exception.ApiException;
import com.ld.security.common.mybatis.base.po.IdsPo;
import com.ld.security.common.mybatis.base.service.ISuperServiceImpl;
import com.ld.security.common.mybatis.core.wrapper.EntityWrapper;
import com.ld.security.common.quartz.QuartzManager;
import com.ld.security.common.quartz.modules.job.constant.JobTaskConstant;
import com.ld.security.common.quartz.modules.job.entity.JobTaskEntity;
import com.ld.security.common.quartz.modules.job.entity.JobTaskTelEntity;
import com.ld.security.common.quartz.modules.job.job.JobArgs;
import com.ld.security.common.quartz.modules.job.mapping.JobTaskMapping;
import com.ld.security.common.quartz.modules.job.service.IJobTaskService;
import com.ld.security.common.quartz.modules.job.service.IJobTaskTelService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
@Slf4j
@Transactional
class JobTaskServiceImpl extends ISuperServiceImpl<JobTaskEntity> implements IJobTaskService {


    @Autowired
    QuartzManager quartzManager;

    @Autowired
    JobTaskMapping jobTaskMapping;

    @Autowired
    private IJobTaskTelService iJobTaskTelService;

    /**

     * 新增任务
     *
     * @param quartz
     * @return
     * @throws Exception
     */
    @SneakyThrows
    @Override

    public int save(JobTaskEntity quartz) {



        JobTaskEntity q =  this.getById(quartz.getId());




        this.isRunThrowEx(q);
        //新增初始化
        if(q == null){
            quartz.setJobStatus(JobTaskConstant.jobStatus.await);
            JobTaskTelEntity taskTelEntity =  iJobTaskTelService.getById(quartz.getTaskTelId());
            quartz.setConfig(taskTelEntity.getConfig());

        }

        quartz.setAppName(appName);

        int total = super.save(quartz);


        return total;
    }


    private void isRunThrowEx(JobTaskEntity q){
        if(q == null){
            return;
        }
        if(q.getJobStatus() == JobTaskConstant.jobStatus.run){
            ApiException.throw400("任务停止后才能执行操作");
        }
    }

    /**
     * 任务删除
     * @param query
     * @return
     */


    @Override
    public int removeByIds(Collection<String> ids) {
        this.stopTask(ids);
        return super.removeByIds(ids);
    }

    @Value("${spring.application.name}")
    private String appName ;

    /**
     * 任务批量启动
     */
   // @PostConstruct
    public void run(){
        JobTaskEntity q = this.newInstance();
        q.setAppName(appName);
        q.setJobStatus(JobTaskConstant.jobStatus.run);
        List<JobTaskEntity> taskList =  this.all(q);
        for (JobTaskEntity qrtzTask : taskList) {
            runTask(qrtzTask);
        }
    }

    @SneakyThrows
    private void runTask(JobTaskEntity jobTask){
        Map args =  new HashMap<>();
        JobTaskTelEntity jobTaskTelEntity =  iJobTaskTelService.getById(jobTask.getTaskTelId());

        args.put(JobArgs.jobConfig,jobTask.getConfig());
        Class cls = Class.forName(jobTaskTelEntity.getJobClassName());
        quartzManager.addOrUpdateJob(cls,jobTask.getId(),jobTask.getGroupId(),jobTask.getCronExpression(),args);
    }

    private int updateJobStatus(List<JobTaskEntity> jobTasks,JobTaskConstant.jobStatus jobStatus){
        if(jobTasks.isEmpty()){
            return 0;
        }
        //批量修改状态
        List<String> ids = jobTasks.stream().map(v -> v.getId()).collect(Collectors.toList());
        JobTaskEntity taskEntity =  this.newInstance();
        taskEntity.setJobStatus(jobStatus);
        UpdateWrapper up = new UpdateWrapper<>();
        up.in("id",ids);


       return jobTaskMapping.update(taskEntity,up);

    }


    @SneakyThrows
    @Override
    public int runTask(Collection<String> ids) {
        int total = 0;
        List<JobTaskEntity> jobTasks = this.listByIds(ids);
        jobTasks = jobTasks.stream().filter(v -> v.getJobStatus() == JobTaskConstant.jobStatus.await)

                .collect(Collectors.toList());

        for (JobTaskEntity jobTask : jobTasks) {
             this.runTask(jobTask);
             total++;
        }


        this.updateJobStatus(jobTasks,JobTaskConstant.jobStatus.run);

        return total;
    }

    @Override
    public int stopTask(Collection<String> ids) {
        int total = 0;
        List<JobTaskEntity> jobTasks =this.listByIds(ids);
        jobTasks = jobTasks.stream().filter(v -> v.getJobStatus() == JobTaskConstant.jobStatus.run)

                .collect(Collectors.toList());

        for (JobTaskEntity jobTask : jobTasks) {
            quartzManager.deleteJob(jobTask.getId(),jobTask.getGroupId());
            total++;
       }
        this.updateJobStatus(jobTasks,JobTaskConstant.jobStatus.await);
        return total;
    }
}